/...
import axiosInstance from './index'
+import Vue from 'vue'
+import TwoFAWindow from '@/components/common/TwoFAWindow'
...
const extendsMethods = {}

+/**
+ * 模拟Promise，达到Promise的then，catch和finally可以重复执行
+ *
+ * @param fn 回调
+ */
+const RepeatablePromise = function (fn) {
+  this.__then = []
+  this.__catch = null
+  this.__finally = null
+  this.then = function (thenFn) {
+    this.__then.push(thenFn)
+    return this
+  }
+  this.catch = function (catchFn) {
+    this.__catch = catchFn
+    return this
+  }
+  this.finally = function (finallyFn) {
+    this.__finally = finallyFn
+    return this
+  }
+  fn(data => {
+    try {
+      let returnData = null
+      for (let i = 0; i < this.__then.length; i++) {
+        if (i === 0) {
+          returnData = this.__then[i](data)
+        } else {
+          returnData = this.__then[i](returnData)
+        }
+      }
+    } catch (e) {
+      if (this.__catch) {
+        throw new Error('Eva: ')
+      }
+      this.__catch && this.__catch(e)
+    }
+    this.__finally && this.__finally()
+  }, e => {
+    this.__catch && this.__catch(e)
+    this.__finally && this.__finally()
+  })
+}
+
...
if (this.__result_promise != null) {
  return this.__result_promise[methodName].apply(this.__result_promise, args)
}
+      // 开启了2FA认证
+      if (this.__with_2fa) {
+        if (this.__2fa_window != null) {
+          this.__result_promise = new RepeatablePromise((resolve, reject) => {
+            this.__2fa_window.$on('then', resolve)
+            this.__2fa_window.$on('catch', reject)
+            this.__2fa_window.$on('cancel', reject)
+          })
+          // - 打开窗口，在此处打开窗口，意味着必须执行then，catch或finally才会打开2fa认证窗口
+          this.__2fa_window.open(axiosInstance, method, this.__arguments)
+        }
+      }
...
+/**
+ * 构建2FA请求对象Promise代理对象
+ *
+ * @param twoFAWindow 2FA认证窗口实例
+ * @returns {{__2fa_window: *, __with_2fa: boolean}}
+ */
+const build2FAPromiseProxy = twoFAWindow => {
+  return {
+    // 2fa标记
+    __with_2fa: true,
+    // 2fa窗口对象
+    __2fa_window: twoFAWindow
+  }
+}
+
/**
 * 扩展方法：开启缓存
...
+/**
+ * 扩展方法：开启2FA认证
+ *
+ * @usage：request.twoFA().[post(), get()...]
+ * @returns {{isExtendsAxiosInstance: boolean, post: Function, get: Function, ...}}
+ */
+extendsMethods.twoFA = function (props) {
+  // 打开2FA窗口
+  let $twoFAWindow = null
+  // - 只有在为获取到密码时（未保存密码或密码已过期）时才打开2FA窗口
+  if (cache.twoFA.getPassword() == null) {
+    const TwoFAWindowVue = Vue.extend(TwoFAWindow)
+    $twoFAWindow = new TwoFAWindowVue({
+      el: document.createElement('div'),
+      propsData: props
+    })
+    document.body.appendChild($twoFAWindow.$el)
+  }
+  let twofaAxiosInstance = {
+    // 标记为axios扩展实例，用于与原生axios作区分
+    isExtendsAxiosInstance: true
+  }
+  if (this.isExtendsAxiosInstance) {
+    twofaAxiosInstance = this
+  }
+  for (const method of requestMethods) {
+    if (twofaAxiosInstance[method] == null) {
+      twofaAxiosInstance[method] = function () {
+        return {
+          ...buildBasePromiseProxy(method, arguments),
+          ...build2FAPromiseProxy($twoFAWindow)
+        }
+      }
+      continue
+    }
+    // 不为null时说明在调用twoFA前调用了其他扩展方法，此时诸如post，get方法的返回值做合并，防止扩展方法丢失。
+    const originMethod = twofaAxiosInstance[method]
+    twofaAxiosInstance[method] = function () {
+      const request = originMethod()
+      Object.assign(request, {
+        ...buildBasePromiseProxy(method, arguments),
+        ...build2FAPromiseProxy($twoFAWindow)
+      })
+      return request
+    }
+  }
+  // 添加扩展方法
+  for (const key in extendsMethods) {
+    twofaAxiosInstance[key] = extendsMethods[key]
+  }
+  return twofaAxiosInstance
+}
+
export default extendsMethods
.../